import { Checkbox } from 'antd'
import React, { PureComponent } from 'react'
import ProTable from '@/components/ProTable'
import styles from './index.less'

/**
 * 角色权限数据权限界面用到的树状checkBox组件
 * 可传入的参数有：
 * disabled: {bool} //是否可以编辑
 * editFieldName {String} //value对象中编辑权限的字段名
 * checkFieldName {String} //value对象中查看权限的字段名
 * titleName {String} //表头第一列显示的标题
 * */

export default class TreeCheckTable extends PureComponent {
  static defaultProps = {
    editFieldName: 'edit',
    checkFieldName: 'check',
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    const { value } = nextProps
    // 当传入的type发生变化的时候，更新state
    if (value !== prevState.workList) {
      if (Array.isArray(value)) {
        const transformedValue = value.map(menu => ({
          ...menu,
          check: menu.readWriteStatus === 1,
          edit: menu.readWriteStatus === 1,
      
      }));
      return {
        workList: transformedValue,
        needUpdate: true,
      };
    }
  }
    // 否则，对于state不进行任何操作
    return null
  }

  constructor(props) {
    super(props)
    this.state = {
      allEditChecked: false,
      allCheckChecked: false,
      allEditIndeterminate: false,
      allCheckIndeterminate: false,
      workList: [],
      needUpdate: true, // 第一次赋值需要运行updateWorkList方法，检测是否要处于半选中状态
    }
  }

  componentDidMount() {
    const { onChange } = this.props
    onChange && onChange(this.state.workList)
  }

  onCheckAll(checked, name) {
    const changeChildrenChecked = (arr) => {
      arr.map((obj) => {
        obj[name] = checked
        if (!checked && name === 'check') {
          obj.edit = false
          obj.editIndeterminate = false
        }
        if (checked && name === 'edit') {
          obj.check = true
        }
        if (name === 'edit') {
          obj.editIndeterminate = false
        } else {
          obj.checkIndeterminate = false
        }
        if (obj.children) {
          changeChildrenChecked(obj.children)
        }
      })
    }
    const { workList } = this.state
    if (!workList || workList?.length < 1) return null
    const data = workList.map((obj) => {
      obj[name] = checked
      if (!checked && name === 'check') {
        obj.edit = false
        obj.editIndeterminate = false
      }
      if (checked && name === 'edit') {
        obj.check = true
      }
      if (name === 'edit') {
        obj.editIndeterminate = false
      } else {
        obj.checkIndeterminate = false
      }
      if (obj.children) {
        changeChildrenChecked(obj.children)
      }
      return obj
    })
    // let data = []
    // data = data.concat(workList)
    this.setState({ workList: data }, () => {
      this.checkAllIndeterminate()
    })
    this.triggerChange(data)
    return null
  }

  triggerChange = (changedValue) => {
    // Should provide an event to pass value to Form.
    const onChange = this.props.onChange
    if (onChange) {
      onChange(changedValue)
    }
  };

  checkAllIndeterminate() {
    const { checkFieldName, editFieldName } = this.props
    const { workList } = this.state
    let {
      allEditChecked, allEditIndeterminate, allCheckChecked, allCheckIndeterminate,
    } = this.state
    if (workList.length === 0) {
      this.setState({
        allCheckIndeterminate: false,
        allEditIndeterminate: false,
      })
      return
    }
    let allEditFalse = true
    let allEditTrue = true
    let allCheckFalse = true
    let allCheckTrue = true
    let hasEditIndeterminate = false
    let hasCheckIndeterminate = false
    workList && workList.map((obj) => {
      if (obj[editFieldName]) {
        allEditFalse = false
      } else {
        allEditTrue = false
      }
      if (obj[checkFieldName]) {
        allCheckFalse = false
      } else {
        allCheckTrue = false
      }
      if (obj.editIndeterminate) {
        hasEditIndeterminate = true
      }
      if (obj.checkIndeterminate) {
        hasCheckIndeterminate = true
      }
    })
    if (allEditFalse) {
      allEditChecked = false
      allEditIndeterminate = false
    } else if (allEditTrue) {
      allEditChecked = true
      allEditIndeterminate = false
    } else {
      allEditChecked = true
      allEditIndeterminate = true
    }
    if (allCheckFalse) {
      allCheckChecked = false
      allCheckIndeterminate = false
    } else if (allCheckTrue) {
      allCheckChecked = true
      allCheckIndeterminate = false
    } else {
      allCheckChecked = true
      allCheckIndeterminate = true
    }
    if (hasCheckIndeterminate && allCheckIndeterminate === false) {
      allCheckIndeterminate = true
    }
    if (hasEditIndeterminate && allEditIndeterminate === false) {
      allEditIndeterminate = true
    }
    this.setState({
      allCheckIndeterminate,
      allEditIndeterminate,
      allCheckChecked,
      allEditChecked,
    })
  }

  updateWorkList() {
    const { checkFieldName, editFieldName } = this.props
    const handleItem = (item) => {
      if (item.children) {
        let allEditFalse = true
        let allEditTrue = true
        let allCheckFalse = true
        let allCheckTrue = true
        item.children.map((obj) => {
          handleItem(obj)
          if (obj[editFieldName]) {
            allEditFalse = false
          } else {
            allEditTrue = false
          }
          if (obj[checkFieldName]) {
            allCheckFalse = false
          } else {
            allCheckTrue = false
          }
        })
        if (allEditFalse) {
          item[editFieldName] = false
          item.editIndeterminate = false
        } else if (allEditTrue) {
          item[editFieldName] = true
          item.editIndeterminate = false
        } else {
          item[editFieldName] = true
          item.editIndeterminate = true
        }
        if (allCheckFalse) {
          item[checkFieldName] = false
          item.checkIndeterminate = false
        } else if (allCheckTrue) {
          item[checkFieldName] = true
          item.checkIndeterminate = false
        } else {
          item[checkFieldName] = true
          item.checkIndeterminate = true
        }
      } else {
        item.checkIndeterminate = false
        item.editIndeterminate = false
      }
    }

    const handleItemIndeterminate = (item) => {
      if (item.children) {
        let hasEditIndeterminate = false
        let hasCheckIndeterminate = false
        item.children.map((obj) => {
          handleItemIndeterminate(obj)
          if (obj.editIndeterminate) {
            hasEditIndeterminate = true
          }
          if (obj.checkIndeterminate) {
            hasCheckIndeterminate = true
          }
        })
        if (hasCheckIndeterminate && item.checkIndeterminate === false) {
          item.checkIndeterminate = true
        }
        if (hasEditIndeterminate && item.editIndeterminate === false) {
          item.editIndeterminate = true
        }
      }
    }
    const { workList } = this.state
    for (let i = 0; i < workList.length; i++) {
      const item = workList[i]
      // 设置子节点的check和indeterminate
      handleItem(item)
      // 当子节点处于check=true且indeterminate=true的情况下，节点自己也需要indeterminate=true
      handleItemIndeterminate(item)
    }
    let data = []
    data = data.concat(workList || [])
    this.setState({ workList: data }, () => {
      this.checkAllIndeterminate()
    })
    this.triggerChange(data)
  }

  render() {
    const {
      checkFieldName, editFieldName, disabled, titleName, ...otherProps
    } = this.props
    const {
      workList, allCheckIndeterminate, allEditIndeterminate, allCheckChecked, allEditChecked, needUpdate,
    } = this.state
    if (needUpdate && workList) {
      this.setState({ needUpdate: false })
      this.updateWorkList()
    }

    return (
      <ProTable
        className={styles.treeCheckTable}
        bordered
        rowKey="key"
        loading={false}
        columns={[
          {
            title: titleName,
            dataIndex: 'name',
            width: '30%',
            key: 'name',
          },
          {
            title: (
              disabled ? (
                <div className={styles.checkboxgroup}>
                  <span
                    className={styles.titleLeft}
                  >
                    查看权限
                  </span>
                  <span>
                    编辑权限
                  </span>
                </div>
              ) : (
                <div className={styles.checkboxgroup}>
                  <Checkbox
                    className={styles.checkboxLeft}
                    checked={allCheckChecked}
                    indeterminate={allCheckIndeterminate}
                    onChange={(e) => {
                      let tempChecked = e.target.checked
                      if (!e.target.checked && allCheckIndeterminate) {
                        tempChecked = true
                      }
                      this.onCheckAll(tempChecked, checkFieldName)
                    }}
                  >
                    查看
                  </Checkbox>
                  <Checkbox
                    checked={allEditChecked}
                    indeterminate={allEditIndeterminate}
                    onChange={(e) => {
                      let tempChecked = e.target.checked
                      if (!e.target.checked && allEditIndeterminate) {
                        tempChecked = true
                      }
                      this.onCheckAll(tempChecked, editFieldName)
                    }}
                  >
                    编辑
                  </Checkbox>
                </div>
              )
            ),
            width: '70%',
            key: checkFieldName,
            render: (text, record, index) => (
              disabled ? (
                <div className={styles.checkboxgroup}>
                  <span
                    className={styles.checkboxLeft}
                    style={{ opacity: record[checkFieldName] ? 1 : 0 }}
                  >
                    查看
                  </span>
                  {/* { */}
                  {/*  ((record.pid === '0') && (!record?.children)) ? <span style={{ opacity: 0 }}>编辑</span> : ( */}
                  {/*    <span */}
                  {/*      style={{ opacity: record[editFieldName] ? 1 : 0 }} */}
                  {/*    > */}
                  {/*      编辑 */}
                  {/*    </span> */}
                  {/*  ) */}
                  {/* } */}
                  <span
                    style={{ opacity: record[editFieldName] ? 1 : 0 }}
                  >
                    编辑
                  </span>
                </div>
              ) : (
                <div className={styles.checkboxgroup}>
                  <Checkbox
                    disabled={(record.pid === '0') && (!record?.children)}
                    className={styles.checkboxLeft}
                    indeterminate={record.checkIndeterminate}
                    checked={record[checkFieldName] || ((record.pid === '0') && (!record?.children))}
                    onChange={(e) => {
                      const handleChildren = (item) => {
                        // 查看取消勾选，编辑也要取消勾选
                        if (!item?.children && !e?.target?.checked) {
                          item.edit = false
                        }
                        if (item.children) {
                          item.children.map((obj) => {
                            handleChildren(obj)
                            obj[checkFieldName] = e.target.checked
                          })
                        }
                      }
                      record[checkFieldName] = e.target.checked
                      handleChildren(record)
                      this.updateWorkList()
                    }}
                  >
                    查看
                  </Checkbox>
                  <Checkbox
                    disabled={(record.pid === '0') && (!record?.children)}
                    indeterminate={record.editIndeterminate}
                    checked={record[editFieldName] || ((record.pid === '0') && (!record?.children))}
                    onChange={(e) => {
                      const handleChildren = (item) => {
                        // 编辑勾选了，查看也要勾选
                        if (!item?.children && e?.target?.checked) {
                          item.check = true
                        }
                        if (item.children) {
                          item.children.map((obj) => {
                            handleChildren(obj)
                            obj[editFieldName] = e.target.checked
                          })
                        }
                      }
                      record[editFieldName] = e.target.checked
                      handleChildren(record)
                      this.updateWorkList()
                    }}
                  >
                    编辑
                  </Checkbox>
                </div>
              )
            ),
          },
        ]}
        dataSource={workList}
        pagination={false}
        {
          ...otherProps
        }
      />
    )
  }
}
